import {
  Component,
  OnInit,
  Input,
  Output,
  OnChanges,
  SimpleChanges,
  EventEmitter,
  ViewChildren,
  QueryList
} from '@angular/core';
import { timer } from 'rxjs';
import { Song } from '@services/data-types/common.type';
import { findIndex } from '@utils/array';
import { SongService } from '@services/song.service';
import { BaseLyricLine, WyyLyric } from './wyy-lyric';
import { WyyScrollComponent } from '../wyy-scroll/wyy-scroll.component';


@Component({
  selector: 'app-wyy-player-panel',
  templateUrl: './wyy-player-panel.component.html',
  styleUrls: ['./wyy-player-panel.component.less']
})
export class WyyPlayerPanelComponent implements OnInit, OnChanges {
  scrollY = 0;
  currentIndex: number;
  currentLyricLines: BaseLyricLine[];
  currentLineNum: number;
  private lyric: WyyLyric;
  private lyricRefs: NodeList;
  private startLine = 2;
  @Input() playing: boolean;
  @Input() songList: Song[];
  @Input() currentSong: Song;
  @Input() show: boolean;
  @Output() onClose = new EventEmitter<void>();
  @Output() onChangeSong = new EventEmitter<Song>();
  @Output() onShareSong = new EventEmitter<Song>();
  @Output() onLikeSong = new EventEmitter<Song | Song[]>();
  @Output() onDeleteSong = new EventEmitter<Song>();
  @Output() onClearSong = new EventEmitter<void>();
  @Output() onSkip = new EventEmitter<[string, number]>();
  @ViewChildren(WyyScrollComponent) private wyyScroll: QueryList<WyyScrollComponent>;
  constructor(private songService: SongService) {}
  ngOnInit() {}
  ngOnChanges(changes: SimpleChanges) {
    if (changes.songList) {
      // 歌单列表数据变化，修改currentIndex
      if (this.currentSong) {
        this.currentIndex = findIndex(this.songList, this.currentSong);
      } else {
        this.currentIndex = -1;
      }
    }
    if (changes.currentSong) {
      if (this.currentSong) {
        this.currentIndex = findIndex(this.songList, this.currentSong);
        this.updateLyric();
        if (this.show) {
          this.scrollToCurrentSong();
        }
      } else {
        // 切换歌曲时执行此操作
        this.resetLyric();
      }
    }
    if (changes.show) {
      if (!changes.show.firstChange && this.show) {
        this.wyyScroll.first.refreshScroll();
        this.wyyScroll.last.refreshScroll();
        timer(80).subscribe(() => {
          if (this.currentSong) {
            this.scrollToCurrentSong(0);
          }
          if (this.lyricRefs) {
            this.scrollToCurrentLyric(0);
          }
        });
      }
    }
    if (changes.playing) {
      if (!changes.playing.firstChange) {
        if (this.lyric) {
          this.lyric.togglePlay(this.playing);
        }
      }
    }
  }
  seekLyric(time: number) {
    if (this.lyric) {
      this.lyric.seek(time);
    }
  }
  private updateLyric() {
    this.resetLyric();
    this.songService.getLyric(this.currentSong.id).subscribe(res => {
      this.lyric = new WyyLyric(res);
      this.currentLyricLines = this.lyric.lines;
      // console.log('currentLyricLines:', this.currentLyricLines);
      this.startLine = res.tlyric ? 1 : 3;
      this.handleLyric();
      this.wyyScroll.last.scrollTo(0, 0);
      if (this.playing) {
        this.lyric.play();
      }
    });
  }
  private handleLyric() {
    this.lyric.handler.subscribe(({ lineNum }) => {
      if (!this.lyricRefs) {
        this.lyricRefs = this.wyyScroll.last.el.nativeElement.querySelectorAll('ul li');
      }
      if (this.lyricRefs.length) {
        this.currentLineNum = lineNum;
        if (lineNum > this.startLine) {
          this.scrollToCurrentLyric(100);
        } else {
          this.wyyScroll.last.scrollTo(0, 0);
        }
      }
    });
  }
  // 歌词重置
  private resetLyric() {
    if (this.lyric) {
      this.lyric.stop();
      this.lyric = null;
      this.currentLineNum = 0;
      this.currentLyricLines = [];
      this.lyricRefs = null;
    }
  }
  private scrollToCurrentSong(speed = 300) {
    const songListRefs = this.wyyScroll.first.el.nativeElement.querySelectorAll('ul li');
    const currentLi = songListRefs[this.currentIndex || 0];
    const offsetTop = currentLi.offsetTop;
    const offsetHeight = currentLi.offsetHeight;
    if (offsetTop - Math.abs(this.scrollY) > offsetHeight * 5 || offsetTop < Math.abs(this.scrollY)) {
      this.wyyScroll.first.scrollToElement(currentLi, speed, false, false);
    }
  }
  private scrollToCurrentLyric(speed = 300) {
    const targetLine = this.lyricRefs[this.currentLineNum - this.startLine];
    if (targetLine) {
      this.wyyScroll.last.scrollToElement(targetLine, speed, false, false);
    }
  }
  shareSong(ev: MouseEvent, song: Song) {
    ev.stopPropagation();
    this.onShareSong.emit(song);
  }
  likeSong(ev: MouseEvent, songs: Song | Song[]) {
    ev.stopPropagation();
    this.onLikeSong.emit(songs);
  }
  deleteSong(ev: MouseEvent, song: Song) {
    ev.stopPropagation();
    this.onDeleteSong.emit(song);
  }
  skipToInfo(ev: MouseEvent, path: [string, number]) {
    ev.stopPropagation();
    if (!path[1]) {
      return;
    }
    this.onSkip.emit(path);
  }
}
